#include "relationeditor.h"
#include "ui_relationeditor.h"

#include "uml/relations/umlrelation.h"
#include "uml/class/umlclassitem.h"
#include "uml/projects/umlclassdiagramm.h"

RelationEditor::RelationEditor(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::RelationEditor)
{
    ui->setupUi(this);

    this->_relation = 0;
    this->_item1 = 0;
    this->_item2 = 0;
    this->_previewRelation = 0;

    this->_scene = new UmlClassDiagramm();
    this->_scene->setSceneRect(0, 0, 280, 180);

    this->ui->graphicsViewPreview->setScene(this->_scene);
    this->ui->graphicsViewPreview->setInteractive(false);

    QWidget::setAttribute(Qt::WA_DeleteOnClose);

    QObject::connect(this->ui->labelLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updatePreview()));
    QObject::connect(this->ui->relationTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePreview()));
    QObject::connect(this->ui->childCardinalityComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePreview()));
    QObject::connect(this->ui->parentCardinalityComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePreview()));
    QObject::connect(this->ui->childRoleLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updatePreview()));
    QObject::connect(this->ui->parentRoleLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updatePreview()));

    QObject::connect(this->ui->pushButtonSave, SIGNAL(clicked()), this, SLOT(save()));
    QObject::connect(this->ui->pushButtonCancel, SIGNAL(clicked()), this, SLOT(cancel()));

    QStringList relationTypes;
    relationTypes << "Assoziation" << "Aggregation" << "Komposition";

    this->ui->relationTypeComboBox->addItems(relationTypes);

    QStringList cardinalities;
    cardinalities << "ausblenden" << "0..1" << "1" << "1 .. *" << "*";

    this->ui->childCardinalityComboBox->addItems(cardinalities);
    this->ui->parentCardinalityComboBox->addItems(cardinalities);
}

RelationEditor::~RelationEditor()
{
    this->_scene->clear();
    delete this->_scene;
    delete ui;
}

void RelationEditor::setRelation(UmlRelation *relation)
{
    this->_relation = relation;
    this->ui->labelLineEdit->setText(this->_relation->name());
    this->ui->parentRoleLineEdit->setText(this->_relation->roleItem1());
    this->ui->childRoleLineEdit->setText(this->_relation->roleItem2());

    QString parentCardinalityText = tr("%1 cardinality").arg(this->_relation->item1()->name());
    QString childCardinalityText = tr("%1 cardinality").arg(this->_relation->item2()->name());

    this->ui->parentCardinalityLabel->setText(parentCardinalityText);
    if (relation->cardinalityItem1().isNull()) {
        this->ui->parentCardinalityComboBox->setCurrentIndex(0);
    } else if (relation->cardinalityItem1() == UmlCardinality("0", "1")) {
        this->ui->parentCardinalityComboBox->setCurrentIndex(1);
    } else if (relation->cardinalityItem1() == UmlCardinality("1", "1")) {
        this->ui->parentCardinalityComboBox->setCurrentIndex(2);
    } else if (relation->cardinalityItem1() == UmlCardinality("1", "*")) {
        this->ui->parentCardinalityComboBox->setCurrentIndex(3);
    } else if (relation->cardinalityItem1() == UmlCardinality("*", "*")) {
        this->ui->parentCardinalityComboBox->setCurrentIndex(4);
    }

    this->ui->childCardinalityLabel->setText(childCardinalityText);
    if (relation->cardinalityItem2().isNull()) {
        this->ui->childCardinalityComboBox->setCurrentIndex(0);
    } else if (relation->cardinalityItem2() == UmlCardinality("0", "1")) {
        this->ui->childCardinalityComboBox->setCurrentIndex(1);
    } else if (relation->cardinalityItem2() == UmlCardinality("1", "1")) {
        this->ui->childCardinalityComboBox->setCurrentIndex(2);
    } else if (relation->cardinalityItem2() == UmlCardinality("1", "*")) {
        this->ui->childCardinalityComboBox->setCurrentIndex(3);
    } else if (relation->cardinalityItem2() == UmlCardinality("*", "*")) {
        this->ui->childCardinalityComboBox->setCurrentIndex(4);
    }

    if (relation->relationIsOfType(UmlRelation::UmlAssociationRelationType))
        this->ui->relationTypeComboBox->setCurrentIndex(0);
    if (relation->relationIsOfType(UmlRelation::UmlAggregationRelationType))
        this->ui->relationTypeComboBox->setCurrentIndex(1);
    if (relation->relationIsOfType(UmlRelation::UmlCompositionRelationType))
        this->ui->relationTypeComboBox->setCurrentIndex(2);

    QString parentRoleText = tr("%1 role name:").arg(this->_relation->item1()->name());
    QString childRoleText = tr("%1 role name:").arg(this->_relation->item2()->name());

    this->ui->parentRoleLabel->setText(parentRoleText);
    this->ui->parentRoleLineEdit->setText(relation->roleItem1());
    this->ui->childRoleLabel->setText(childRoleText);
    this->ui->childRoleLineEdit->setText(relation->roleItem2());

    this->updatePreview();
}

void RelationEditor::changeEvent(QEvent *e)
{
    QDialog::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void RelationEditor::save()
{
    this->_relation->setText(this->ui->labelLineEdit->text());

    this->_relation->setRoleItem1(this->ui->parentRoleLineEdit->text());
    this->_relation->setRoleItem2(this->ui->childRoleLineEdit->text());

    switch (this->ui->parentCardinalityComboBox->currentIndex()) {
    case 0:
        this->_relation->setCardinalityItem1(UmlCardinality());
        break;
    case 1:
        this->_relation->setCardinalityItem1(UmlCardinality("0", "1"));
        break;

    case 2:
        this->_relation->setCardinalityItem1(UmlCardinality("1", "1"));
        break;

    case 3:
        this->_relation->setCardinalityItem1(UmlCardinality("1", "*"));
        break;

    case 4:
        this->_relation->setCardinalityItem1(UmlCardinality("*", "*"));
        break;
    }

    switch (this->ui->childCardinalityComboBox->currentIndex()) {
    case 0:
        this->_relation->setCardinalityItem2(UmlCardinality());
        break;

    case 1:
        this->_relation->setCardinalityItem2(UmlCardinality("0", "1"));
        break;

    case 2:
        this->_relation->setCardinalityItem2(UmlCardinality("1", "1"));
        break;

    case 3:
        this->_relation->setCardinalityItem2(UmlCardinality("1", "*"));
        break;

    case 4:
        this->_relation->setCardinalityItem2(UmlCardinality("*", "*"));
        break;
    }

    switch(this->ui->relationTypeComboBox->currentIndex()) {
    case 0 :
        this->_relation->setRelationType(UmlRelation::UmlAssociationRelationType);
        break;
    case 1 :
        this->_relation->setRelationType(UmlRelation::UmlAggregationRelationType);
        break;
    case 2 :
        this->_relation->setRelationType(UmlRelation::UmlCompositionRelationType);
        break;
    }

    this->done(QDialog::Accepted);
}

void RelationEditor::cancel()
{
    this->done(QDialog::Rejected);
}

void RelationEditor::updatePreview()
{
    if (!this->_relation) {
        return;
    }

    if (!this->_item1) {
        this->_item1 = new UmlClassItem();
        this->_item1->setProject(this->_scene);
        this->_item1->setShowAtts(false);
        this->_item1->setShowMeths(false);
        this->_item1->setText(this->_relation->item1()->name());
        this->_item1->setPos(this->_scene->sceneRect().right() - this->_item1->boundingRect().width() - 20, 5);

        this->_scene->addItem(this->_item1);
    }


    if (!this->_item2) {
        this->_item2 = new UmlClassItem();
        this->_item2->setProject(this->_scene);
        this->_item2->setShowAtts(false);
        this->_item2->setShowMeths(false);
        this->_item2->setText(this->_relation->item2()->name());
        this->_item2->setPos(20, this->_scene->sceneRect().bottom() - this->_item2->boundingRect().height() - 5);

        this->_scene->addItem(this->_item2);
    }

    if (!this->_previewRelation) {
        this->_previewRelation = new UmlRelation();
        this->_previewRelation->setRelationType(this->_relation->relationType());
        this->_previewRelation->setProject(this->_scene);
        this->_previewRelation->setItems(this->_item1, this->_item2);
    }

    this->_previewRelation->setText(this->ui->labelLineEdit->text());

    switch (this->ui->parentCardinalityComboBox->currentIndex()) {
    case 0 :
        this->_previewRelation->setCardinalityItem1(UmlCardinality());
        break;
    case 1 :
        this->_previewRelation->setCardinalityItem1(UmlCardinality("0", "1"));
        break;
    case 2 :
        this->_previewRelation->setCardinalityItem1(UmlCardinality("1", "1"));
        break;
    case 3 :
        this->_previewRelation->setCardinalityItem1(UmlCardinality("1", "*"));
        break;
    case 4 :
        this->_previewRelation->setCardinalityItem1(UmlCardinality("*", "*"));
        break;
    }

    switch (this->ui->childCardinalityComboBox->currentIndex()) {
    case 0 :
        this->_previewRelation->setCardinalityItem2(UmlCardinality());
        break;
    case 1 :
        this->_previewRelation->setCardinalityItem2(UmlCardinality("0", "1"));
        break;
    case 2 :
        this->_previewRelation->setCardinalityItem2(UmlCardinality("1", "1"));
        break;
    case 3 :
        this->_previewRelation->setCardinalityItem2(UmlCardinality("1", "*"));
        break;
    case 4:
        this->_previewRelation->setCardinalityItem2(UmlCardinality("*", "*"));
        break;
    }

    this->_previewRelation->setRoleItem2(this->ui->childRoleLineEdit->text());
    this->_previewRelation->setRoleItem1(this->ui->parentRoleLineEdit->text());

    switch(this->ui->relationTypeComboBox->currentIndex()) {
    case 0 :
        this->_previewRelation->setRelationType(UmlRelation::UmlAssociationRelationType);
        break;
    case 1 :
        this->_previewRelation->setRelationType(UmlRelation::UmlAggregationRelationType);
        break;
    case 2 :
        this->_previewRelation->setRelationType(UmlRelation::UmlCompositionRelationType);
        break;
    }
}
